 /*
    Copyright 2006-2011 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/** \file
    Declaration of the sfrhist_snapshot class.  \ingroup sfrhist */

// $Id$

#ifndef __sfrhist_snapshot__
#define __sfrhist_snapshot__

#include "boost/function/function1.hpp"
#include "boost/shared_ptr.hpp"
#include <vector>
#include "preferences.h"
#include "model.h"
#include "bhmodel.h"
#include <map>
#include "snapshot.h"
#include <memory>

namespace CCfits {
  class HDU;
  class ExtHDU;
};

namespace boost {
  template<typename> class shared_ptr;
};

namespace mcrx {
  class sfrhist_snapshot;
};

template<typename T> class onedva;


/** Derived Snapshot class for SED calculation. This has the
    additional features that it knows about progenitor galaxies, can
    assign metallicities and formation times, and has SEDs for
    luminous particles.  The actual calculations of these values are
    delegated to either the stellar model or the callers in
    sfrhist. \ingroup sfrhist */
class mcrx::sfrhist_snapshot: public mcrx::Snapshot {
public:
  typedef boost::function<std::pair<double,double>(int, const particle_set_generic&, int, particle_set_generic&)> T_age_metallicity_functor;

private:
  /// Vector to parent object Snapshots objects. (Initial SNAPshots)
  std::vector<boost::shared_ptr<Snapshot> > isnaps;
  std::vector<int> isnap_sizes;
  int min_id;

  /// Vector of SED arrays for the particle species. Gas/halo species are empty.
  std::vector<array_2> SED_set;
  std::vector<array_1> L_bol_set;
  int n_lambda;

  // these data members are only used when writing the FITS file
  std::string SED_unit, L_unit;

  // functions for assigning ages/metallicities/seds
  std::pair<int, unsigned int> deduce_progenitor(unsigned int ID) const;

  void add_cm(species s,
	      boost::function<bool(int,const particle_set_generic*const,int)> predicate,
	      std::vector<vec3d>& cm, std::vector<double>& m) const;

  void write_fits_set (CCfits::ExtHDU& output, species s) const;


public:
  // Constructor loads the snapshot as well as the progenitor snapshots.
  sfrhist_snapshot (const Preferences& gp, const Preferences& p, 
		    const std::string& snapshot_file,
		    const std::string& snapshot_name,
		    const std::vector<std::string>& progenitors);
  ~sfrhist_snapshot () {};

  void assign_age_metallicity (const species s,
			       const std::vector<boost::shared_ptr<T_age_metallicity_functor> >& f_age_metallicity);
  void calculate_oldpop_massloss(const stellarmodel& m);
  void calculate_stellar_SEDs(const stellarmodel& m);
  void calculate_BH_SEDs(const bhmodel& m);
  void calculate_L_bol (const stellarmodel& m);

  std::vector<mcrx::vec3d> calculate_centers () const;
  void change_origin(const mcrx::vec3d&);

  /** Returns the number of initial objects in this snapshot, based on
      the isnaps vector. */
  int nobject() const {return isnaps.size();};

  /** Writes the star particle sets to the PARTICLEDATA table in a
      FITS file. */
  void write_fits_table (const std::string& output_file_name) const;

};

#endif


